package database;

import java.sql.*;

/**
 * @author Hsu琛君珩
 * @ClassName:DataBase
 * @date 2023-12-18
 * @apiNote
 * @Version: v1.0
 */

/**
 * 数据库操作类，用于用户注册和登录验证。
 * 使用单例模式进行数据库连接的管理。
 */
public class DataBase {

    // 使用单例模式的DataBase实例。这意味着整个应用程序中将只有一个DataBase实例。
    private static DataBase instance;
    // 数据库驱动的名称。这里使用的是MySQL数据库的JDBC驱动。
    private static final String DRIVER_NAME = "com.mysql.jdbc.Driver"; // MySQL数据库的JDBC驱动名称
    // 数据库URL。这是数据库服务器的地址和要连接的数据库的名称。
    // "jdbc:mysql://" 是JDBC连接MySQL数据库的固定格式。
    // "localhost:3306" 指定了数据库服务器的地址和端口（MySQL默认端口是3306）
    // "test" 是要连接的数据库名称。
    private static final String DBURL = "jdbc:mysql://localhost:3306/test";
    // 数据库表名
    private static final String DBTABLE_NAME = "user";
    // 数据库用户名。用于登录数据库
    private static final String DBUSER = "root";
    // 数据库密码。用于登录数据库
    private static final String DBPWD = "123456";

    /**
     * 私有构造器。
     * 这个构造器是私有的，这意味着无法从类的外部直接创建DataBase类的实例。
     * 这是单例模式的一部分，确保只有一个DataBase实例被创建。
     */
    private DataBase() {
        try {
            // 加载数据库驱动。
            // Class.forName()方法用于动态加载指定类名的类，这里用于加载数据库驱动。
            // 如果找不到指定的驱动类，则会抛出ClassNotFoundException异常。
            Class.forName(DRIVER_NAME);
        } catch (ClassNotFoundException e) {
            // 打印异常堆栈跟踪信息。
            // 这是异常处理的一部分，可以帮助诊断问题的原因。
            e.printStackTrace();
        }
    }

    /**
     * 获取DataBase类的单例实例。
     * 这是一个静态方法，用于获取DataBase类的实例。
     * 如果实例尚未创建，它会创建一个新的实例。如果已经存在，它将返回现有的实例。
     * 这样可以确保整个应用程序中只有一个DataBase实例。
     *
     * @return DataBase类的单例实例
     */
    public static DataBase getInstance() {
        // 检查实例是否已经被创建。
        // 如果instance为null，意味着尚未创建实例。
        if (instance == null) {
            // 创建一个新的DataBase实例。
            instance = new DataBase();
        }
        // 返回DataBase实例。
        return instance;
    }

    /**
     * 用户注册验证。
     * 此方法用于验证新用户注册，确保用户名是唯一的。
     *
     * @param username 用户名
     * @param password 密码hash
     * @return 是否注册成功。如果用户名已存在，返回false；如果成功添加新用户，返回true。
     */
    public boolean registerVerify(String username, String password) {
        try (Connection connection = DriverManager.getConnection(DBURL, DBUSER, DBPWD);
             Statement statement = connection.createStatement();
             PreparedStatement write = connection.prepareStatement("insert into " + DBTABLE_NAME + " (username,password) values(?,?)")) {

            // 查询数据库中是否已存在相同用户名的用户
            ResultSet read = statement.executeQuery("select * from " + DBTABLE_NAME);
            while (read.next()) {
                String existUser = read.getString("username");
                // 如果发现已存在的用户名与新注册的用户名相同，返回false表示注册失败
                if (existUser.equals(username)) {
                    return false; // 用户已存在
                }
            }
            // 将新用户添加到数据库中
            write.setString(1, username);
            write.setString(2, password);
            write.executeUpdate();
            System.out.println("向数据库中添加新用户: 用户名:" + username + " 密码:" + password);
            return true; // 注册成功
        } catch (SQLException e) {
            // 打印异常信息
            e.printStackTrace();
        }
        return false; // 发生异常，注册失败
    }

    /**
     * 用户登录验证。
     * 此方法用于验证用户登录，检查用户名和密码是否匹配。
     *
     * @param username 用户名
     * @param password 密码hash
     * @return 是否登录成功。如果用户名和密码匹配，返回true；否则返回false。
     */
    public boolean loginVerify(String username, String password) {
        try (Connection connection = DriverManager.getConnection(DBURL, DBUSER, DBPWD);
             Statement statement = connection.createStatement()) {

            // 查询数据库中的用户信息
            ResultSet read = statement.executeQuery("select * from " + DBTABLE_NAME);
            while (read.next()) {
                String existUser = read.getString("username");
                String existPassword = read.getString("password");
                // 检查用户名和密码是否匹配
                if (existUser.equals(username) && existPassword.equals(password)) {
                    return true; // 登录成功
                }
            }
        } catch (SQLException e) {
            // 打印异常信息
            e.printStackTrace();
        }
        return false; // 登录失败
    }
}
